#|
    L.I.S.P.: Lots of irritating and silly parentheses
    Homework 6: Macros
    
    Henrique "Nican" Polido
    Keleigh O'Neil
|#

;; A class is a function that intakes a name of a function and arguments
;; And executes that function with the initial given variables
(define-syntax class
  (syntax-rules(initvars method)
    [(class (initvars args ...)
       (method funcname extra ...) ...)     
     (lambda (args ...)
       (lambda (name)
         [cond 
           [(symbol=? 'funcname name) (lambda extra ...)] ...
           ]))]))

;; Executes the given class given the function name, with all the  extra arguments
(define-syntax send
  (syntax-rules()
    [(send obj funcname args ...)
      ((obj 'funcname) args ...)
     ]))


;;Example given in assignment
(define dillo-class
  (class (initvars length dead?)
    (method longer-than? (len) (> length len))
    (method run-over () (dillo-class (+ length 1) true))))

;;something that resembles check-expects
(define d3 (dillo-class 5 false))
(send d3 longer-than? 6)
(send d3 longer-than? 5)
(define d4 (send d3 run-over))
(send d4 longer-than? 5)

;; policy-checker returns a function that will white-list all the access types 
;;and return true if the access is given; otherwise will return false
(define-syntax policy-checker
  (syntax-rules()
  [(policy-checker
     (group (accesstype ...) (access ...)) ...)
   (lambda (input-group input-accesstype input-access)
     (not (boolean? (or (and
            (symbol=? 'group input-group)
                   (member input-accesstype (list 'accesstype ...))
                   (member input-access (list 'access ...))) ...
                                                             ))))]))

;;Example given in assignment
(define check-policy
     (policy-checker
      (programmer (read write) (code documentation))
      (tester (read) (code))
      (tester (write) (documentation))
      (manager (read write) (reports))
      (manager (read) (documentation))
      (ceo (read write) (code documentation reports))))

;;something that resembles check-expects
(check-policy 'programmer 'write 'code)
(check-policy 'programmer 'write 'reports)

